package com.j.lemon.learn.enc;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

/**
 * @author lijunjun
 * @title: RsaUtil
 * @description: TODO
 * @date 2023/8/320:08
 */
public class RsaUtil {
    private static final String PUBLICKEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiNI0++J2RDsY6FCl9+mWqI7TV68TO7ZIXEKlVB140HDcTuj7KdboXrZPANbqdqEY9OCmvh12yFiKy+olzp8YEOULBHiC+xiSopLsuznywvTdwsltXBsa8/gONxp7cd2qA0YpYjgWeX2nk+l0Cm/VJ8AnYyKcbMwKOdn2wF5X826wEmDQb9q3u5v/4dcExFloalg3cmsnDbkxZQ2Pa7ZrGJ/yRxMbUfIdWGp/cN+NTeyefIvuxQJemIAPdjhKr4qIIoezULQP4V1zoXL8NQH7c2q53SIu1WcJaKj4OcC7MZ0gIF5UDY4XhNczNHMnnuoLuoNhggzwzQHkHlZCPewANQIDAQAB";
    private static final String PRIVATEKEY = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCI0jT74nZEOxjoUKX36ZaojtNXrxM7tkhcQqVUHXjQcNxO6Psp1uhetk8A1up2oRj04Ka+HXbIWIrL6iXOnxgQ5QsEeIL7GJKikuy7OfLC9N3CyW1cGxrz+A43Gntx3aoDRiliOBZ5faeT6XQKb9UnwCdjIpxszAo52fbAXlfzbrASYNBv2re7m//h1wTEWWhqWDdyaycNuTFlDY9rtmsYn/JHExtR8h1Yan9w341N7J58i+7FAl6YgA92OEqviogih7NQtA/hXXOhcvw1AftzarndIi7VZwloqPg5wLsxnSAgXlQNjheE1zM0cyee6gu6g2GCDPDNAeQeVkI97AA1AgMBAAECggEAHQVhYbAmX9CdNuGsYop0f2pUH7wt+zNt48vrH41ky+m0gTRf2f8QqM5Isafkcac4EPD5zUeYo2RMhHY08L/ELgk3LgqV1cbfi4ZYmlnvSTUBOMja3neNXwRVl5CRcJSQ9ELUklXNRpXFjtUs3O3dq6HRePCld1pMLPszoJgiVarsEoOK2veaE3AN4pH0NmdeXIGd/TAbTotZbq9jmf/zzXVfbVhnw3mppXFbD9ksQaKan+NbWIDabgyKEdQzxLNu9veHDwREebPCsOXlrpikj2lTWEN0Keow72AUWTAzT2Z8dpq3RQyj5Q6c63mqBvfZNVlNyOcPO1O8L4i7+MLswQKBgQDMFmZ3mkMgUVUxFXg2Pb/0vCfz0+lOGb5cxRr8eFavVTmpMxz3KnTq9dX31T8ngV/nqGMuoyN9xbE02WTSiUpawHrqLKyKk3StaQsvMt7AoaycJyrE/PYgcJcHWGRnG0lqdvd41W3XNLJ4rG8gV5UWycxrz6/JlWyOYMOcIS658QKBgQCrn5xTqyKOr20R99p0k2NGyN+mAC8A4p6yL7Sng52mx6s362Tt9VWn0lP9r+qmF7UrUaVPx3tEgsEmesBl2INm0KDsTh9JYSGUilh301Yzw9c4sp5T4wrHKlOw4UbiFNuC4yaftAe0LF7QHPi2N+uFtFHC/myxmxXU+KcUzSXGhQKBgQClYSWJl+z7XE0PqFkwgxtxA6PQdxFg44WaAXNb0VxVWleOX8gCFlqGJ85KtXgm2DTSMWal3TcebTurGtsTrIMfRUiVSLxM0y7CcxPIHI3bRWftZePHm0ELipEoN52s27TDXEIvnawTrzVMilbGu5Ip1D8dwj+tt7MvMQRyGYWW0QKBgEph3usUXOHifi8vcOrdhkWDggr8QWLs1UL9EhsYHBfQqhCOYSwRDJKzwdtNhzF9TPP9atxs5KwIz5XR1dlOQYUqHtTL9xtikZ9DZpxoaA//bSQRpjVNTbqMScF7obESwSC1OmQ1LrGUGXOxWsn+6oEEaftNMea4BHpNWnzVfO3RAoGAAW7tcnwNnwf5WN4nZjjTSFTGxNjKTdyqWzIIfFGRuxWZzp71qKaMWiPvvKYHEzmb5Qhi+DDjZl4uZTL3xYiqaAsU7AKkaiOmbC2g8tILRCNk+huo8+h/hBLMp/4oDKaO/lZLY6uKrpzq/Y1+2o7dz6fWtNtdmQTOeXfuCOMdsMk=";


    public static RsaKeys generateRsaKeys() {
        try {
            // 选择算法
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            // 设置密钥长度
            keyPairGenerator.initialize(2048);
            // 生成密钥对
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            // 获取私钥和公钥
            PrivateKey privateKey = keyPair.getPrivate();
            PublicKey publicKey = keyPair.getPublic();
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey.getEncoded());
            byte[] encoded = pkcs8EncodedKeySpec.getEncoded();
            String privateKeyStr= Base64.encodeBase64String(encoded);


            PKCS8EncodedKeySpec publicd = new PKCS8EncodedKeySpec(publicKey.getEncoded());
            byte[] pencoded = publicd.getEncoded();
            String publicKeyStr = Base64.encodeBase64String(pencoded);
            return new RsaKeys(publicKeyStr,privateKeyStr);
        } catch (Exception e) {
            throw new RuntimeException("生成rsa密钥对失败！",e);
        }
    }

    public static String rsaEnc(String publicKey,String content) {
        try {
            Cipher cipher = Cipher.getInstance("RSA");
            byte[] decode = Base64.decodeBase64(publicKey);
            X509EncodedKeySpec pkcs8EncodedKeySpec = new X509EncodedKeySpec(decode);
            PublicKey rsa = KeyFactory.getInstance("RSA").generatePublic(pkcs8EncodedKeySpec);
            cipher.init(Cipher.ENCRYPT_MODE,rsa);
            byte[] bytes = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
            return Base64.encodeBase64String(bytes);
        } catch (Exception e) {
            throw new RuntimeException("rsa加密失败！",e);
        }
    }

    public static String rsaDec(String privateKeyStr,String content){
        try {
            byte[] decode = Base64.decodeBase64(privateKeyStr);
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(decode);
            PrivateKey pk = KeyFactory.getInstance("RSA").generatePrivate(pkcs8EncodedKeySpec);
            byte[] bytes = Base64.decodeBase64(content);
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE,pk);
            byte[] bytes1 = cipher.doFinal(bytes);
            return new String(bytes1, StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new RuntimeException("rsa解密失败！",e);
        }
    }

    public static String sign(String privateKeyStr,String message) {
        try {
            byte[] decode = Base64.decodeBase64(privateKeyStr);
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(decode);
            PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(pkcs8EncodedKeySpec);
            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initSign(privateKey);
            signature.update(message.getBytes());
            byte[] signatureBytes = signature.sign();
            return Base64.encodeBase64String(signatureBytes);
        } catch (Exception e) {
            throw new RuntimeException("rsa签名失败！",e);
        }
    }


    public static boolean verify(String publicKey,String message, String signature)  {
        try {
            byte[] decode = Base64.decodeBase64(publicKey);
            X509EncodedKeySpec pkcs8EncodedKeySpec = new X509EncodedKeySpec(decode);
            PublicKey pk = KeyFactory.getInstance("RSA").generatePublic(pkcs8EncodedKeySpec);
            Signature verifier = Signature.getInstance("SHA256withRSA");
            verifier.initVerify(pk);
            verifier.update(message.getBytes());
            byte[] signatureBytes = Base64.decodeBase64(signature);
            return verifier.verify(signatureBytes);
        } catch (Exception e) {
            throw new RuntimeException("rsa验签失败!",e);
        }
    }

    public static class RsaKeys{
        public RsaKeys() {
        }

        public RsaKeys(String publicKey, String privateKey) {
            this.publicKey = publicKey;
            this.privateKey = privateKey;
        }
        private String publicKey;
        private String privateKey;

        public String getPublicKey() {
            return publicKey;
        }

        public void setPublicKey(String publicKey) {
            this.publicKey = publicKey;
        }

        public String getPrivateKey() {
            return privateKey;
        }

        public void setPrivateKey(String privateKey) {
            this.privateKey = privateKey;
        }
    }

    public static void main(String[] args) {

        RsaKeys rsaKeys = generateRsaKeys();
        String publicKey = rsaKeys.publicKey;
        String privateKey = rsaKeys.privateKey;
        System.out.println(publicKey);
        System.out.println(privateKey);
//        String s = rsaEnc(PUBLICKEY, publicKey);
//        System.out.println(s);
//        String s1 = rsaDec(PRIVATEKEY, s);
//        System.out.println(s1);
//
//        String s = SMHelper.sm4Encrypt("qwewqesasdgfdsaa", rsaKeys.publicKey);
//        System.out.println(s);


//        String content = "这个是请求body";
//        String s = rsaEnc(PUBLICKEY, content);
//        String s1 = rsaDec(PRIVATEKEY, s);
//        System.out.println("解密："+s1);
//
//        String asdasdasd = sign("asdasdasd", PRIVATEKEY);
//        System.out.println("sign:"+asdasdasd);
//        boolean asdasdasd1 = verify("asdasdasd", asdasdasd, PUBLICKEY);
//        System.out.println(asdasdasd1);



    }


}
